/**
 * Repository cloning, document summarization, and Coze mind map generation.
 */

import { spawn } from "node:child_process";
import { existsSync, mkdirSync, readdirSync, readFileSync, writeFileSync, statSync } from "node:fs";
import { join, basename } from "node:path";
import { fetch } from "undici";

export interface MindmapInput {
  repoUrl: string;
  branch?: string;
  targetDir?: string;
  summaryFile: string;
  prompt: string;
}

// Executes the 'git clone' command.
async function gitClone(repoUrl: string, targetDir: string, branch?: string): Promise<void> {
  return new Promise<void>((resolve, reject) => {
    // Use --depth=1 for a shallow clone to speed up the process.
    const args = ["clone", "--depth=1"];
    if (branch) {
      args.push("-b", branch);
    }
    args.push(repoUrl, targetDir);

    console.log(`[Mindmap] Cloning repository: git ${args.join(' ')}`);
    const gitProcess = spawn("git", args, { stdio: "pipe", shell: process.platform === "win32" });

    let stderr = '';
    gitProcess.stderr.on('data', (data) => {
        stderr += data.toString();
    });

    gitProcess.on("close", (code) => {
      if (code === 0) {
        console.log(`[Mindmap] Successfully cloned to ${targetDir}`);
        resolve();
      } else {
        console.error(`[Mindmap] git clone failed with code ${code}:\n${stderr}`);
        reject(new Error(`git clone failed with exit code: ${code}\n${stderr}`));
      }
    });

    gitProcess.on("error", (err) => {
        console.error('[Mindmap] Failed to start git process:', err);
        reject(err);
    });
  });
}

// Recursively collects Markdown files from a directory.
function collectMarkdownFiles(dir: string, fileList: string[] = []): string[] {
  const entries = readdirSync(dir);
  for (const entry of entries) {
    // Avoid traversing the .git directory for efficiency.
    if (entry === '.git') continue;

    const fullPath = join(dir, entry);
    try {
        const stat = statSync(fullPath);
        if (stat.isDirectory()) {
            collectMarkdownFiles(fullPath, fileList);
        } else if (stat.isFile() && (entry.toLowerCase().endsWith(".md") || entry.toLowerCase() === 'readme')) {
            fileList.push(fullPath);
        }
    } catch (error) {
        console.warn(`[Mindmap] Could not stat file ${fullPath}, skipping.`, error);
    }
  }
  return fileList;
}

// Merges collected markdown files into a single summary file.
function buildSummary(mdFiles: string[], outputPath: string): string {
  console.log(`[Mindmap] Merging ${mdFiles.length} markdown files...`);
  const summaryContent = mdFiles.map(file => {
    try {
      const content = readFileSync(file, "utf-8");
      // Add a clear header for each file's content.
      return `\n\n# File: ${basename(file)}\n\n${content}`;
    } catch (error) {
      console.warn(`[Mindmap] Could not read file ${file}, skipping.`, error);
      return '';
    }
  }).join("\n\n---\n");

  writeFileSync(outputPath, summaryContent, "utf-8");
  console.log(`[Mindmap] Summary written to ${outputPath}`);
  return summaryContent;
}

// Calls the Coze workflow to generate a mind map URL.
async function runCozeWorkflow(inputText: string): Promise<string> {
  // IMPORTANT: These credentials should ideally be stored in environment variables, not hardcoded.
  const cozeToken = "pat_Pu15WHtxIHKeO4HtE9F6u5LVwSjIGoRyAsV4zduNWsQFZe0sxy0HPeIIxnJAqfhJ";
  const workflowId = "7535494365978214438";
  const appId = "7535445185598308415";
  const apiUrl = 'https://api.coze.cn/v1/workflow/run';

  console.log(`[Mindmap] Calling Coze workflow with input of length ${inputText.length}...`);

  const response = await fetch(apiUrl, {
    method: 'POST',
    headers: {
      'Authorization': `Bearer ${cozeToken}`,
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({
      workflow_id: workflowId,
      app_id: appId,
      parameters: { input: inputText },
      is_async: false,
    }),
  });

  if (!response.ok) {
    const errorText = await response.text();
    console.error(`[Mindmap] Coze API request failed: ${response.status}`, errorText);
    throw new Error(`Coze API request failed: ${response.status} ${response.statusText}`);
  }

  const result = await response.json() as any;
  
  if (result.code !== 0) {
    console.error('[Mindmap] Coze API returned an error:', result);
    throw new Error(`Coze API returned an error: ${result.msg || 'Unknown error'}`);
  }

  let mindmapUrl: string | undefined;

  // CRITICAL FIX: The 'data' field is a stringified JSON, so it needs to be parsed first.
  if (result.data && typeof result.data === 'string') {
    try {
      const parsedData = JSON.parse(result.data);
      mindmapUrl = parsedData?.output;
    } catch (e) {
      console.error('[Mindmap] Failed to parse the `data` string from Coze API response:', e);
      // Let it fall through to the error handler below.
    }
  }

  if (!mindmapUrl || typeof mindmapUrl !== 'string') {
    const fullResponse = JSON.stringify(result, null, 2);
    console.error('[Mindmap] Could not find mind map URL in Coze response. Full response:', fullResponse);
    throw new Error(`Could not find mind map URL in Coze API response. Full response:
${fullResponse}`);
  }

  console.log(`[Mindmap] Successfully generated mind map URL: ${mindmapUrl}`);
  return mindmapUrl;
}

// Main exported function for the tool.
export async function cloneRepoAndMindmap(input: MindmapInput) {
  const targetDir = input.targetDir || basename(input.repoUrl, ".git");
  if (!existsSync(targetDir)) {
    mkdirSync(targetDir, { recursive: true });
  }

  await gitClone(input.repoUrl, targetDir, input.branch);

  const mdFiles = collectMarkdownFiles(targetDir);
  const summaryPath = join(targetDir, input.summaryFile);
  const summaryContent = buildSummary(mdFiles, summaryPath);

  const finalInput = input.prompt ? `${input.prompt}\n\n${summaryContent}` : summaryContent;
  const outputUrl = await runCozeWorkflow(finalInput);

  return {
    repoDir: targetDir,
    summaryFile: summaryPath,
    mindmapUrl: outputUrl,
    message: "Repository cloned, documents summarized, and mind map link generated successfully."
  };
}